package com.cloud.util;

import org.apache.tomcat.jni.OS;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.logging.Logger;

/**
 * @author Henry.Song
 * @version 2020/11/25
 * @description 媒体文件辅助类
 */
public class MediaUtil {

    private static final Logger LOG = Logger.getLogger(MediaUtil.class.getName());

    private static final String Avi2Mp4CommandLineLinux = "%s -i %s -c:v libx264 -strict -2 %s -y";
    private static final String Avi2Mp4CommandLineMac = "%s -i %s -c copy -map 0 %s -y";

    private static final String CommonCommandLine = "%s -i %s -vcodec copy -acodec copy -y %s";

    public static final String VIDEO = "video";
    public static final String IMAGE = "image";
    public static final String OTHER = "";

    public static final String MEDIA_AVI = "avi";
    public static final String MEDIA_MP4 = "mp4";
    public static final String MEDIA_FLV = "flv";
    public static final String MEDIA_MKV = "mkv";
    public static final String MEDIA_MOV = "mov";
    public static final String MEDIA_WMV = "wmv";

    // Can not convert by ffmpeg commoncommandline directly.
    public static final String MEDIA_MPEG = "mpeg";
    public static final String MEDIA_RMVB = "rmvb";


    public static final String videoSuffix[] = {
            "mp4", "avi", "mov", "wmv",
            "asf", "navi", "3gp", "mkv",
            "f4v", "rmvb", "webm", "mpeg"
    };

    public static final String imgSuffix[] = {
            "bmp", "jpg", "jpeg", "png",
            "tiff", "gif", "pcx", "tga",
            "exif", "fpx", "svg", "psd",
            "cdr", "pcd", "dxf", "ufo",
            "eps", "ai", "raw", "wmf"
    };

    public static boolean isVideoFile(String fileName) {
        for (int i = 0; i < videoSuffix.length; i++) {
            if (!fileName.endsWith(".")) {
                int lastDotIdx = fileName.lastIndexOf(".");
                if (lastDotIdx != -1 && videoSuffix[i].equalsIgnoreCase(fileName.substring(lastDotIdx + 1)))
                    return true;
            }
        }
        return false;
    }

    public static boolean isImageFile(String fileName) {
        for (int i = 0; i < imgSuffix.length; i++) {
            if (!fileName.endsWith(".")) {
                int lastDotIdx = fileName.lastIndexOf(".");
                if (lastDotIdx != -1 && imgSuffix[i].equalsIgnoreCase(fileName.substring(lastDotIdx + 1)))
                    return true;
            }
        }
        return false;
    }

    public static String getFileSuffix(String fileName) {
        if (!fileName.endsWith(".")) {
            int lastDotIdx = fileName.lastIndexOf(".");
            return fileName.substring(lastDotIdx + 1).toLowerCase();
        }
        return "";
    }

    public static String getMediaType(String fileName) {
        if (isVideoFile(fileName)) return VIDEO;
        if (isImageFile(fileName)) return IMAGE;
        return OTHER;
    }

    private static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (Exception e) {
            }
        }
    }

    public static boolean AviToMp4(String ffmpegPath, String srcFilePath, String destFilePath) {
        return CommonConvert(ffmpegPath, srcFilePath, destFilePath);
    }

    public static boolean FlvToMp4(String ffmpegPath, String srcFilePath, String destFilePath) {
        return CommonConvert(ffmpegPath, srcFilePath, destFilePath);
    }

    public static boolean MkvToMp4(String ffmpegPath, String srcFilePath, String destFilePath) {
        return CommonConvert(ffmpegPath, srcFilePath, destFilePath);
    }

    public static boolean MovToMp4(String ffmpegPath, String srcFilePath, String destFilePath) {
        return CommonConvert(ffmpegPath, srcFilePath, destFilePath);
    }

    public static boolean WmvToMp4(String ffmpegPath, String srcFilePath, String destFilePath) {
        return CommonConvert(ffmpegPath, srcFilePath, destFilePath);
    }

    public static boolean CommonConvert(String ffmpegPath, String srcFilePath, String destFilePath) {
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader reader = null;
        try {
            //String ffmpegConvertCommandLine = Avi2Mp4CommandLineLinux;
            //if (OSUtil.isMacOS() || OSUtil.isMacOSX()) {
            //    ffmpegConvertCommandLine = Avi2Mp4CommandLineMac;
            //}
            String cmd = String.format(CommonCommandLine, ffmpegPath, srcFilePath, destFilePath);
            LOG.info(String.format("ffmpeg cmd: %s", cmd));
            Process p = Runtime.getRuntime().exec(cmd);
            p.waitFor();
            if (p.exitValue() != 0) {
                return false;
            }
            is = p.getInputStream();
            isr = new InputStreamReader(is);
            reader = new BufferedReader(isr);
            String str = null;
            StringBuilder sb = new StringBuilder();
            while ((str = reader.readLine()) != null) {
                sb.append(str);
            }
            LOG.info("ffmepg convert:\n" + sb.toString());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            closeQuietly(reader);
            closeQuietly(isr);
            closeQuietly(is);
        }
    }


    public static boolean isInConvertList(String mediaType) {
        return MediaUtil.MEDIA_AVI.equals(mediaType)
                || MediaUtil.MEDIA_FLV.equals(mediaType)
                || MediaUtil.MEDIA_MKV.equals(mediaType)
                || MediaUtil.MEDIA_MOV.equals(mediaType)
                || MediaUtil.MEDIA_WMV.equals(mediaType);
    }

    public static void main(String[] args) {

        boolean flag1 = FlvToMp4("/usr/local/bin/ffmpeg",
                "/Users/henry/Workspace/source/SpringBoot-CityCloud-Vue/media/1528856730709247.flv",
                "/Users/henry/Workspace/source/SpringBoot-CityCloud-Vue/media/1528856730709247_flv_convert.mp4");

        System.out.println("FlvToMp4: " + flag1);

        boolean flag2 = MkvToMp4("/usr/local/bin/ffmpeg",
                "/Users/henry/Workspace/source/SpringBoot-CityCloud-Vue/media/1528856730709247.mkv",
                "/Users/henry/Workspace/source/SpringBoot-CityCloud-Vue/media/1528856730709247_mkv_convert.mp4");
        System.out.println("MkvToMp4: " + flag2);

        boolean flag3 = MovToMp4("/usr/local/bin/ffmpeg",
                "/Users/henry/Workspace/source/SpringBoot-CityCloud-Vue/media/1528856730709247.mov",
                "/Users/henry/Workspace/source/SpringBoot-CityCloud-Vue/media/1528856730709247_mov_convert.mp4");
        System.out.println("MovToMp4: " + flag3);

        boolean flag5 = WmvToMp4("/usr/local/bin/ffmpeg",
                "/Users/henry/Workspace/source/SpringBoot-CityCloud-Vue/media/1528856730709247.wmv",
                "/Users/henry/Workspace/source/SpringBoot-CityCloud-Vue/media/1528856730709247_wmv_convert.mp4");
        System.out.println("WmvToMp4: " + flag5);

        boolean flag4 = AviToMp4("/usr/local/bin/ffmpeg",
                "/Users/henry/Workspace/source/SpringBoot-CityCloud-Vue/media/1528856730709247.avi",
                "/Users/henry/Workspace/source/SpringBoot-CityCloud-Vue/media/1528856730709247_avi_convert.mp4");
        System.out.println("AviToMp4: " + flag4);


    }
}
